// fs_operation.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>

#include "fs_operation.h"

// 根目录
static FileNode *root = NULL;

char writing_file[128];
int8_t writing_flag = false;
int8_t chunk_count = 0;
// 初始化文件系统
void init_file_system() {
    root = (FileNode *)malloc(sizeof(FileNode));
    if(root == NULL){
        printf("[nl_debug] init_file_system内存分配失败\n");
        return;
    }
    strcpy(root->name, "/");
    root->type = FILE_TYPE_DIRECTORY;
    root->parent = NULL;
    root->first_child = NULL;
    root->next_sibling = NULL;
}

// 分割路径为数组
static char **split_path(const char *path, int *count) {
    char *path_copy = strdup(path);
    if(path_copy == NULL){
        printf("[nl_debug] split_path strdup失败\n");
        *count = 0;
        return NULL;
    }

    char *token = strtok(path_copy, "/");
    char **tokens = NULL;
    int token_count = 0;

    while (token != NULL) {
        char **new_tokens = realloc(tokens, sizeof(char *) * (token_count + 1));
        if(new_tokens == NULL){
            printf("[nl_debug] split_path realloc失败\n");
            // 释放已分割的部分
            for(int i = 0; i < token_count; i++){
                free(tokens[i]);
            }
            free(tokens);
            free(path_copy);
            *count = 0;
            return NULL;
        }
        tokens = new_tokens;
        tokens[token_count++] = strdup(token);
        if(tokens[token_count-1] == NULL){
            printf("[nl_debug] split_path strdup token失败\n");
            // 释放已分割的部分
            for(int i = 0; i < token_count-1; i++){
                free(tokens[i]);
            }
            free(tokens);
            free(path_copy);
            *count = 0;
            return NULL;
        }
        token = strtok(NULL, "/");
    }

    free(path_copy);
    *count = token_count;
    return tokens;
}

// 通过路径查找节点
static FileNode *find_node(const char *path) {
    if (strcmp(path, "/") == 0) {
        return root;
    }

    int count = 0;
    char **tokens = split_path(path, &count);
    if(tokens == NULL){
        printf("[nl_debug] find_node split_path失败\n");
        return NULL;
    }

    FileNode *current = root;

    for (int i = 0; i < count && current != NULL; i++) {
        FileNode *child = current->first_child;
        while (child != NULL) {
            if (strcmp(child->name, tokens[i]) == 0) {
                current = child;
                break;
            }
            child = child->next_sibling;
        }
        if (child == NULL) {
            current = NULL;
            break;
        }
    }

    for (int i = 0; i < count; i++) {
        free(tokens[i]);
    }
    free(tokens);
    return current;
}

// 创建新文件
void command_touch(char *path) {
    int count = 0;
    char **tokens = split_path(path, &count);
    if (tokens == NULL || count == 0) {
        printf("路径无效\n");
        return;
    }
    FileNode *current = root;
    for (int i = 0; i < count - 1; i++) {
        // 查找或创建中间目录
        FileNode *child = current->first_child;
        while (child != NULL) {
            if (strcmp(child->name, tokens[i]) == 0 && child->type == FILE_TYPE_DIRECTORY) {
                break;
            }
            child = child->next_sibling;
        }
        if (child == NULL) {
            // 创建目录
            child = (FileNode *)malloc(sizeof(FileNode));
            if(child == NULL){
                printf("内存分配失败\n");
                goto cleanup;
            }
            strcpy(child->name, tokens[i]);
            child->type = FILE_TYPE_DIRECTORY;
            child->parent = current;
            child->first_child = NULL;
            child->next_sibling = current->first_child;
            current->first_child = child;
        }
        current = child;
    }
    // 创建文件
    char *file_name = tokens[count - 1];
    FileNode *child = current->first_child;
    while (child != NULL) {
        if (strcmp(child->name, file_name) == 0) {
            printf("文件已存在：%s\n", path);
            goto cleanup;
        }
        child = child->next_sibling;
    }
    FileNode *file = (FileNode *)malloc(sizeof(FileNode));
    if(file == NULL){
        printf("内存分配失败\n");
        goto cleanup;
    }
    strcpy(file->name, file_name);
    file->type = FILE_TYPE_FILE;
    file->parent = current;
    file->first_child = NULL;
    file->next_sibling = current->first_child;
    current->first_child = file;

cleanup:
    for (int i = 0; i < count; i++) {
        free(tokens[i]);
    }
    free(tokens);
}


// 列出目录内容，返回文件节点数组和文件数量
FileNode** command_ls(char *path, int *count) {
    if (path == NULL || strlen(path) == 0) {
        path = "/";
    }
    printf("[Debug] command_ls called with path: %s\n", path); // 调试信息
    FileNode *dir = find_node(path);
    if (dir == NULL ) {
        printf("没有这个目录：%s\n", path);
        *count = 0;
        return NULL;
    } else if (dir->type != FILE_TYPE_DIRECTORY) {
        printf("不是目录：%s\n", path);
        *count = 0;
        return NULL;
    }
    // 统计目录下的文件数量
    int num_files = 0;
    FileNode *child = dir->first_child;
    while (child != NULL) {
        num_files++;
        child = child->next_sibling;
    }
    printf("[Debug] Number of files/directories in '%s': %d\n", path, num_files); // 调试信息
    // 处理空目录情况
    if (num_files == 0) {
        *count = 0;
        return NULL;
    }
    // 分配文件节点数组
    FileNode **file_list = (FileNode**)malloc(sizeof(FileNode*) * num_files);
    if (file_list == NULL) {
        printf("内存分配失败\n");
        *count = 0;
        return NULL;
    }
    // 将文件节点复制到数组中
    child = dir->first_child;
    int index = 0;
    while (child != NULL) {
        file_list[index++] = child;
        // 打印每个文件的类型
        printf("[Debug] file_list[%d] = %s (%s)\n", index-1, child->name, 
               child->type == FILE_TYPE_DIRECTORY ? "Directory" : "File");
        child = child->next_sibling;
    }
    *count = num_files;
    return file_list;
}

// 删除文件或目录
void command_rm(char *path) {
    FileNode *node = find_node(path);
    if (node == NULL || node == root) {
        printf("无法删除：%s\n", path);
        return;
    }
    // 从父节点中移除
    FileNode *parent = node->parent;
    if (parent->first_child == node) {
        parent->first_child = node->next_sibling;
    } else {
        FileNode *sibling = parent->first_child;
        while (sibling->next_sibling != node) {
            sibling = sibling->next_sibling;
            if(sibling == NULL){
                printf("内部错误：无法找到兄弟节点\n");
                return;
            }
        }
        sibling->next_sibling = node->next_sibling;
    }

    free_node(node);
}

// 递归释放节点
void free_node(FileNode *node) {
    FileNode *child = node->first_child;
    while (child != NULL) {
        FileNode *next_child = child->next_sibling;
        free_node(child);
        child = next_child;
    }
    free(node);
}

// 创建新目录
void command_mkdir(char *path){
    int count = 0;
    char **tokens = split_path(path, &count);
    if (tokens == NULL || count == 0) {
        printf("路径无效\n");
        return;
    }
    FileNode *current = root;
    for (int i = 0; i < count; i++) {
        // 查找或创建中间目录
        FileNode *child = current->first_child;
        while (child != NULL) {
            if (strcmp(child->name, tokens[i]) == 0 && child->type == FILE_TYPE_DIRECTORY) {
                break;
            }
            child = child->next_sibling;
        }
        if (child == NULL) {
            // 创建目录
            child = (FileNode *)malloc(sizeof(FileNode));
            if(child == NULL){
                printf("内存分配失败\n");
                goto cleanup;
            }
            strcpy(child->name, tokens[i]);
            child->type = FILE_TYPE_DIRECTORY;
            child->parent = current;
            child->first_child = NULL;
            child->next_sibling = current->first_child;
            current->first_child = child;
        }
        current = child;
    }

    for (int i = 0; i < count; i++) {
        free(tokens[i]);
    }
    free(tokens);
    return;

cleanup:
    for (int i = 0; i < count; i++) {
        free(tokens[i]);
    }
    free(tokens);
}

// 创建或更新文件内容
void command_write(char *path, char *data) {
    if (path == NULL || data == NULL) {
        printf("路径或数据为空\n");
        return;
    }

    FileNode *node = find_node(path);
    if (node == NULL) {
        // 文件不存在，创建新文件
        command_touch(path);
        node = find_node(path);
        if (node == NULL) {
            printf("无法创建文件：%s\n", path);
            return;
        }
    }

    if (node->type != FILE_TYPE_FILE) {
        printf("路径不是文件：%s\n", path);
        return;
    }

    // 释放旧内容
    if (node->data != NULL) {
        free(node->data);
    }

    // 分配并复制新内容
    node->data = strdup(data);
    if (node->data == NULL) {
        printf("内存分配失败\n");
    } else {
        printf("写入成功到文件：%s\n", path);
    }
}

// 显示文件内容
char* command_cat(char *path) {
    if (path == NULL) {
        printf("路径为空\n");
        return NULL;
    }

    FileNode *node = find_node(path);
    if (node == NULL) {
        printf("文件不存在：%s\n", path);
        return NULL;
    }

    if (node->type != FILE_TYPE_FILE) {
        printf("路径不是文件：%s\n", path);
        return NULL;
    }

    if (node->data != NULL) {
        printf("%s\n", node->data);
        return node->data;
    } else {
        printf("文件为空：%s\n", path);
        return NULL;
    }
}